var path = require('path');
var fs = require('fs');
var webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin'); //打包时候连同html一起打包
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')

var autoprefixer = require('autoprefixer');
var version = require("./package.json").version;
var projectName = require("./package.json").name;

function makeConf(options) {
    options = options || {};
    var dev = options.dev || false;
    var env = options.env;
    var proDir = process.cwd(); //当前项目目录
    var srcDir = path.resolve(proDir, 'src');
    // var buidDir = path.resolve(proDir, 'build/wap/' + projectName + "/" + version + "/"); //项目编译后的保存目录
    var buidDir = path.resolve(proDir, 'build/'); //项目编译后的保存目录
    var webpackBuidPath = path.resolve(proDir, '__build'); //webpack 编译的虚拟目录
    //console.log('srcDir:' + srcDir);
    var entries = genEntries(srcDir, dev);
    var chunks = Object.keys(entries);
    var config = {
        // srcDir: srcDir,
        // buidDir: buidDir,
        entry: entries,
        output: {
            path: dev ? webpackBuidPath : buidDir, //必须是绝对路径
            devtoolModuleFilenameTemplate: '[resource-path]',
            sourceMapFilename: "[file].map",
            filename: dev ? '[name].js' : 'scripts/[name].[chunkhash:8].js',
            chunkFilename: dev ? '[id].common.js' : 'scripts/[id].[chunkhash:8].common.min.js',
            publicPath: dev ? '' : `` //页面中引入的url路径前缀（css，js） 相对路径 ， `/${projectName}/${version}/`
        },
        module: {
            rules: [{
                    test: /\.(tpl|ejs)$/,
                    loader: 'ejs'
                },
                {
                    test: /\.js$/,
                    exclude: /(node_modules|bower_components)/,
                    loader: "babel-loader",
                    query: { // 参数
                        presets: [
                            'env',
                            'stage-0'
                        ],
                        cacheDirectory: true,
                        plugins: ['transform-remove-strict-mode', 'add-module-exports', 'typecheck', 'transform-decorators-legacy']
                    }
                },
                {
                    test: /\.(jpe?g|png|gif|svg)$/i,
                    //注意后面的name=xx，这里很重要否则打包后会出现找不到资源的
                    loader: 'url-loader?limit=2&minetype=images/jpg&name=images/[name].[ext]'
                },
                {
                    test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?/i,
                    loader: 'url-loader?limit=8124&name=fonts/[name].[ext]'
                }
            ]
        },
        resolve: {
            alias: {
                // 'zepto': path.resolve(srcDir, 'scripts/lib/zepto.js'),
                // 'jquery': path.resolve(srcDir, 'scripts/lib/jquery.min.js'),
                '_': path.resolve(proDir, 'node_modules/underscore/underscore.js')
            },
            extensions: ['.js', '.css', '.png', '.jpg', '.less'] //开启后缀名的自动补全
        },
        externals: {},
        plugins: [
            new webpack.ProvidePlugin({ //$ jQuery 使用当前resolve的jquery
                // $: "jquery",
                // 'window.$': 'jquery',
                _: '_',
                'window._': '_',
            }),
            new webpack.DefinePlugin({
                // API_PATH: env == "prod" ? JSON.stringify('') : JSON.stringify("https://www.fastmock.site/mock/12f22611cffc1d868c3f435812322338") // /nat
                API_PATH: '"http://api.hljpckj.com"'
            }),
            new CopyWebpackPlugin([{
                from: path.resolve(__dirname, './src/emoji'), // 不打包直接输出的文件
                to: 'emoji', // 打包后静态文件放置位置
                ignore: ['.*'] // 忽略规则。（这种写法表示将该文件夹下的所有文件都复制）
            }]),

        ],
        performance: {

            hints: "warning", // 枚举

            maxAssetSize: 3000000, // 整数类型（以字节为单位）

            maxEntrypointSize: 5000000, // 整数类型（以字节为单位）

            assetFilter: function(assetFilename) {

                // 提供资源文件名的断言函数

                return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');

            }

        },
        optimization: {
            minimizer: [
                new TerserPlugin({
                    cache: true,
                    parallel: true // 使用多进程并行运行和文件缓存来提高构建速度
                }),
                new OptimizeCssAssetsPlugin({
                    cssProcessorOptions: {
                        // map: {
                        // 	inline: false // https://blog.csdn.net/nesxiaogu/article/details/89314483
                        // }
                    }
                })
            ]
        }
        // sassLoader: {
        //   includePaths: [proDir + "/node_modules/compass-mixins/lib"]
        // }
    }
    /**
     * 自动生成入口文件放到页面引入，入口js名必须和入口文件名相同
     * 如果html文件名称和入口js 文件不同命，会把所有js css 都打包到html里面
     */
    var pages = fs.readdirSync(srcDir);

    pages.forEach(function(filename) {
        var m = filename.match(/(.+)\.html$/);
        if (m) {
            // @see https://github.com/kangax/html-minifier
            var conf = {
                template: path.resolve(srcDir, filename),
                // @see https://github.com/kangax/html-minifier
                minify: {
                    collapseWhitespace: true,
                    removeComments: true
                },
                inject: true,
                /*
                          title: 用来生成页面的 title 元素
                          filename: 输出的 HTML 文件名，默认是 index.html, 也可以直接配置带有子目录。
                          template: 模板文件路径，支持加载器，比如 html!./index.html
                          inject: true | 'head' | 'body' | false  ,注入所有的资源到特定的 template 或者 templateContent 中，如果设置为 true 或者 body，所有的 javascript 资源将被放置到 body 元素的底部，'head' 将放置到 head 元素中。
                          favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。
                          minify: {} | false , 传递 html-minifier 选项给 minify 输出
                          hash: true | false, 如果为 true, 将添加一个唯一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件，对于解除 cache 很有用。
                          cache: true | false，如果为 true, 这是默认值，仅仅在文件修改之后才会发布文件。
                          showErrors: true | false, 如果为 true, 这是默认值，错误信息会写入到 HTML 页面中
                          chunks: 允许只添加某些块 (比如，仅仅 unit test 块)
                          chunksSortMode: 允许控制块在添加到页面之前的排序方式，支持的值：'none' | 'default' | {function}-default:'auto'
                          excludeChunks: 允许跳过某些块，(比如，跳过单元测试的块) 
                          */
                filename: filename
            };

            if (m[1] in config.entry) {
                conf.inject = 'body';
                conf.chunks = ['manifest', 'common', m[1]];
            }
            config.plugins.push(new HtmlWebpackPlugin(conf)); //打包时候连同html一起打包
        }
    });

    if (dev) {
        // css直接内嵌
        //console.log(proDir + "/node_modules/compass-mixins/lib")
        config.mode = 'development';
        var cssLoader = {
            test: /\.css$/,
            use: ['style-loader', 'css-loader', 'postcss-loader']
        };
        var lessLoader = {
            test: /\.less/,
            use: ['style-loader', "css-loader", 'postcss-loader', "less-loader"]
        };
        var htmlLoader = {
            test: /\.html$/,
            use: 'html-loader'
        }

        config.module.rules.push(cssLoader);

        config.module.rules.push(lessLoader);
        config.module.rules.push(htmlLoader);
        config.devtool = "#cheap-module-source-map";

        config.plugins.push(new webpack.HotModuleReplacementPlugin());
    } else {
        config.mode = 'production';
        const MiniCssLoadersConf = {
            css: [
              {
                loader:MiniCssExtractPlugin.loader,
                options:{
                    publicPath: '../'
                }
            },
                {
                    loader: "css-loader",

                }
            ],
            less: [
              {
                loader:MiniCssExtractPlugin.loader,
                options:{
                    publicPath: '../'
                }
            },
                {
                    loader: "css-loader",
     
                },
                {
                    loader: "less-loader",

                }
            ]
        };
        // css分离出来单独文件引入
        var cssLoader = {
            test: /\.css$/,
            use: MiniCssLoadersConf.css,

        };
        var lessLoader = {
            test: /\.less$/,
            use: MiniCssLoadersConf.less
        };

        var htmlLoader = {
            test: /\.html$/,
            use: "html-loader?minimize=false"
        };

        config.module.rules.push(cssLoader);
        config.module.rules.push(lessLoader);
        config.module.rules.push(htmlLoader);

        config.plugins.push(
            new MiniCssExtractPlugin({
                filename: 'css/[name].[chunkhash:8].css',
            })
        );
        config.plugins.push(
            new webpack.optimize.SplitChunksPlugin({ //提取公用的代码打包到独立文件
                cacheGroups: {
                    vendor: {
                        name: "vendor",
                        test: /[\\/]node_modules[\\/]/,
                        chunks: "all",
                        priority: 10 // 优先级
                    },
                    common: {
                        name: "common",
                        test: /[\\/]src[\\/]/,
                        minSize: 1024,
                        chunks: "all",
                        priority: 5
                    }
                }
            })
        );
        config.plugins.push(
            new webpack.optimize.RuntimeChunkPlugin({
                name: "manifest" // 分离 “webpack运行时”打包
            }),
        );
        config.plugins.push(new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
        }));
    }
    return config;
}

//所有的入口文件
var entryFiles = {};

function getAllFiles(path) {
    var files = fs.readdirSync(path);
    files.forEach(function(file) {
        let stat = fs.statSync(path + '/' + file);
        if (stat.isDirectory()) {
            // 如果是文件夹遍历
            getAllFiles(path + '/' + file);
        } else {
            entryFiles[path + '/' + file] = file;
        }
    });
}

function genEntries(srcDir, isDev) {
    var map = {};
    var jsDir = path.resolve(srcDir, 'scripts');
    var entryDir = path.resolve(jsDir, 'entry');
    getAllFiles(entryDir);
    //   console.log(JSON.stringify(entryFiles, null, 2));
    for (let dir in entryFiles) {
        var name = entryFiles[dir];
        var m = name.match(/(.+)\.js$/);
        var entry = m ? m[1] : '';
        var entryPath = dir;
        var paths = [];
        if (isDev) {
            paths.push('webpack/hot/dev-server');
        }
        paths.push(entryPath);
        if (entry) map[entry] = paths;
    }
    //   console.log(map)
    return map;
}
module.exports = makeConf;